package com.xflib.shardingsphere.service.impl;

import com.blazebit.persistence.CriteriaBuilder;
import com.blazebit.persistence.CriteriaBuilderFactory;
import com.xflib.shardingsphere.entity.Order;
import com.xflib.shardingsphere.repository.OrderRepository;
import com.xflib.shardingsphere.service.OrderService;
import com.xflib.shardingsphere.utils.CustomBeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

/**
 * 订单业务层接口实现类
 *
 * @author Jiahai
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderRepository orderRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Order save(Order order) {
        return orderRepository.save(order);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long orderId) {
        orderRepository.deleteById(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Order update(Order order) {
        Order orderOriginal = orderRepository.findById(order.getOrderId())
                .orElseThrow(() -> new RuntimeException("ID不存在"))
                .setOrderName(order.getOrderName())
                .setUserId(order.getUserId());
        CustomBeanUtils.copyPropertiesIgnoreNull(order, orderOriginal);
        return orderRepository.save(orderOriginal);
    }

    @Override
    public Order findById(Long orderId) {
        return orderRepository.findById(orderId).orElseThrow(() -> new RuntimeException("ID不存在"));
    }

    @Override
    public List<Order> list() {
        return orderRepository.findAll(Sort.by(Sort.Direction.ASC, Order.ORDER_ID));
    }

    @Override
    public Page<Order> page(int page, int size) {
        PageRequest pageRequest = PageRequest.of(page > 0 ? page - 1 : 0, size, Sort.by(Sort.Direction.DESC, Order.ORDER_ID));
        return this.orderRepository.findAll(pageRequest);
    }

    @Override
    public List<Order> findByOrderName(String orderName) {
        CriteriaBuilder<Order> cb = cbf.create(em, Order.class, "o");
        return cb.where(getColumnAlias("o", Order.ORDER_NAME)).eq(orderName).getResultList();
    }

    @Autowired
    CriteriaBuilderFactory cbf;

    @PersistenceContext
    EntityManager em;

    private static final String getColumnAlias(String tableAlias, String columnName) {
        return tableAlias.concat(".").concat(columnName);
    }
}
